package com.qf.lock;

import java.sql.Time;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 锁降级的学习
 */
public class LockDegradation implements Runnable {

    /**
     * 读写锁
     */
    private ReentrantReadWriteLock reentrantReadWriteLock;

    public LockDegradation() {
        reentrantReadWriteLock = new ReentrantReadWriteLock();
    }

    @Override
    public void run() {
        while (true) {
            try {
                update();
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void update() throws Exception {
        reentrantReadWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread() + "【获取写锁】");

            System.out.println(Thread.currentThread() + "写数据到DB或者共享变量");
            TimeUnit.SECONDS.sleep(1);

            reentrantReadWriteLock.readLock().lock();
            System.out.println(Thread.currentThread() + "【获取读锁】");
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
            System.out.println(Thread.currentThread() + "【释放写锁】锁降级结束,降级为读锁");
            // 锁降级结束,降级为读锁
        }

        System.out.println(Thread.currentThread() + "当前线程消费数据，其他读线程（本博客没有实现）此时也可以消费数据");
        TimeUnit.SECONDS.sleep(1);

        System.out.println(Thread.currentThread() + "当前线程消费数据完成，释放读锁");
        reentrantReadWriteLock.readLock().unlock();
    }

    public static void main(String[] args) {
        LockDegradation lockDegradation = new LockDegradation();
        Thread thread1 = new Thread(lockDegradation);
        Thread thread2 = new Thread(lockDegradation);
        Thread thread3 = new Thread(lockDegradation);
        thread1.start();
        thread2.start();
        thread3.start();
        while (true) {
        }
    }
}
